package com.example.amoocspringboot.filter;

import com.example.amoocspringboot.util.JwtUtil;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.ExpiredJwtException;
import io.jsonwebtoken.MalformedJwtException;
import io.jsonwebtoken.UnsupportedJwtException;
import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Collections;

@Component
public class JwtTokenAuthenticationFilter extends OncePerRequestFilter {
    
    private static final Logger logger = LoggerFactory.getLogger(JwtTokenAuthenticationFilter.class);
    
    @Override
    protected void doFilterInternal(HttpServletRequest request, 
                                  @NotNull HttpServletResponse response, 
                                  @NotNull FilterChain filterChain) throws ServletException, IOException {
        try {
            // 获取token
            String token = getTokenFromRequest(request);
            
            if (!StringUtils.hasText(token)) {
                // 无token，继续过滤器链
                filterChain.doFilter(request, response);
                return;
            }
            
            // 解析并验证token
            Claims claims = validateAndParseToken(token);
            String userId = extractUserId(claims);
            
            // 创建认证对象（这里简化处理，实际应该加载用户信息和权限）
            UsernamePasswordAuthenticationToken authentication = 
                new UsernamePasswordAuthenticationToken(userId, null, Collections.emptyList());
            
            // 设置认证信息到Spring Security上下文
            SecurityContextHolder.getContext().setAuthentication(authentication);
            
            logger.debug("用户 {} 认证成功", userId);
            
        } catch (ExpiredJwtException e) {
            logger.warn("Token已过期: {}", e.getMessage());
            SecurityContextHolder.clearContext();
        } catch (UnsupportedJwtException | MalformedJwtException e) {
            logger.warn("Token格式错误: {}", e.getMessage());
            SecurityContextHolder.clearContext();
        } catch (Exception e) {
            logger.error("Token验证失败: {}", e.getMessage());
            SecurityContextHolder.clearContext();
        }
        
        // 继续过滤器链
        filterChain.doFilter(request, response);
    }
    
    /**
     * 从请求中提取token
     */
    private String getTokenFromRequest(HttpServletRequest request) {
        String bearerToken = request.getHeader("Authorization");
        if (StringUtils.hasText(bearerToken) && bearerToken.startsWith("Bearer ")) {
            return bearerToken.substring(7);
        }
        
        // 兼容旧的token header
        return request.getHeader("token");
    }
    
    /**
     * 验证并解析token
     */
    private Claims validateAndParseToken(String token) {
        try {
            return JwtUtil.parseToken(token);
        } catch (ExpiredJwtException e) {
            throw new ExpiredJwtException(e.getHeader(), e.getClaims(), "Token已过期");
        } catch (UnsupportedJwtException e) {
            throw new UnsupportedJwtException("不支持的JWT格式");
        } catch (MalformedJwtException e) {
            throw new MalformedJwtException("JWT格式错误");
        } catch (Exception e) {
            throw new RuntimeException("Token验证失败", e);
        }
    }
    
    /**
     * 从Claims中提取用户ID
     */
    private String extractUserId(Claims claims) {
        Object userId = claims.get("id");
        if (userId == null) {
            throw new RuntimeException("Token中缺少用户ID信息");
        }
        return userId.toString();
    }
}
